package com.example.trackcircuitdiagnosis.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.trackcircuitdiagnosis.entity.MysqlBack;
import com.example.trackcircuitdiagnosis.mapper.MysqlBackMapper;
import com.example.trackcircuitdiagnosis.service.IMysqlBackService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 数据库备份表 服务实现类
 * </p>
 *
 * @author ChengYuan Mao
 * @since 2022-12-26
 */
@Service
public class MysqlBackServiceImpl extends ServiceImpl<MysqlBackMapper, MysqlBack> implements IMysqlBackService {

    @Value("${track.resource.path}")
    private String dbPath;

    @Autowired
    private MysqlBackMapper mysqlBackMapper;

    /**
     * 数据库备份
     */
    @Override
    public void databaseBack() {
        String sdf = DateUtil.format(new Date(), "yyyyMMdd");;
        // 数据库文件名称
        StringBuilder mysqlFileName = new StringBuilder()
                .append("/sql-new")
                .append(sdf)
                .append(".sql");
        // 备份命令
        StringBuilder backCmd = new StringBuilder()
                .append("mysqldump ")
                .append("track_circuit_diagnosis")
                .append(" -uroot")
                .append(" -pTcfd2024@")
                .append(" > ")
                .append(dbPath)
                .append(mysqlFileName);
        System.out.println(backCmd);
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        String[] command = new String[0];
        if (osName.contains("windows")) {
            // Windows
            command = new String[]{"cmd.exe", "/c", String.valueOf(backCmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(backCmd)};
        }
        try {
            // 获取Runtime实例
            Process exec = Runtime.getRuntime().exec(command);
            System.out.println(exec.waitFor());            System.out.println(getStreamStr(exec.getErrorStream()));
            System.out.println(getStreamStr(exec.getInputStream()));
            System.out.println("Mysql 数据库备份成功,备份文件名："+ mysqlFileName);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("网络异常，数据库备份失败");
        }

        // 删除命令
        StringBuilder removeCmd = new StringBuilder()
                .append("sudo ")
                .append("rm ")
                .append(dbPath)
                .append(mysqlFileName);
        if (osName.contains("windows")) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(removeCmd) + ".gz"};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(removeCmd)  + ".gz"};
        }
        try {
            // 获取Runtime实例
            Process exec = Runtime.getRuntime().exec(command);
            System.out.println(exec.waitFor());
            System.out.println(getStreamStr(exec.getErrorStream()));
            System.out.println(getStreamStr(exec.getInputStream()));
            System.out.println("Mysql 数据库备份删除成功,备份文件名："+ mysqlFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 压缩命令
        StringBuilder gzipCmd = new StringBuilder()
                .append("sudo ")
                .append("gzip ")
                .append(dbPath)
                .append(mysqlFileName);
        System.out.println(gzipCmd);
        if (osName.contains("windows")) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(gzipCmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(gzipCmd)};
        }
        try {
            // 获取Runtime实例
            Process exec = Runtime.getRuntime().exec(command);
            System.out.println(exec.waitFor());
            System.out.println(getStreamStr(exec.getErrorStream()));
            System.out.println(getStreamStr(exec.getInputStream()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        mysqlFileName.append(".gz");
        //删除数据
        QueryWrapper<MysqlBack> mysqlBackQueryWrapper = new QueryWrapper<>();
        mysqlBackQueryWrapper.eq("file",String.valueOf(mysqlFileName));
        remove(mysqlBackQueryWrapper);

        //插入数据库中
        MysqlBack mysqlBack = new MysqlBack();
        mysqlBack.setCreateTime(LocalDateTime.now());
        mysqlBack.setFile(String.valueOf(mysqlFileName));
        File file=new File(dbPath+String.valueOf(mysqlFileName));
        long size = file.length();

        mysqlBack.setSize(size);
        mysqlBackMapper.insert(mysqlBack);

        String time = DateUtil.format(DateUtil.offsetDay(new Date(), -7), "yyyyMMdd");
        mysqlFileName = new StringBuilder()
                .append("/sql-new")
                .append(time)
                .append(".sql")
                .append(".gz");
        // 删除命令
        removeCmd = new StringBuilder()
                .append("sudo ")
                .append("rm ")
                .append(dbPath)
                .append(mysqlFileName);
        if (osName.contains("windows")) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(removeCmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(removeCmd)};
        }
        try {
            // 获取Runtime实例
            Runtime.getRuntime().exec(command);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //删除数据
        mysqlBackQueryWrapper = new QueryWrapper<>();
        mysqlBackQueryWrapper.eq("file",String.valueOf(mysqlFileName));
        remove(mysqlBackQueryWrapper);
    }

    @Override
    /**
     * 获取MysqlBack list
     * @return list
     */
    public List<MysqlBack> getList() {
        return mysqlBackMapper.selectList(null);
    }

    public static String getStreamStr(InputStream is) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "GBK"));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        br.close();
        return sb.toString();
    }

}
